<?php

/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

/**
 * Description of NTB_Controller
 *
 * @author Nguyen Thai Binh
 */
class NTB_Core_Controller extends MX_Controller {

  protected $module = '';
  protected $module_path = '';
  protected $module_lang = '';
  protected $class = '';

  public function __construct() {
    parent::__construct();
    $this->lang->load($this->config->item('language'), $this->config->item('language'));
    if (!isset($this->acl))
      $this->load->library('acl', null, null, 'admin');
    $permission = $this->acl->check_acl(userdata('groups'));
    if (!$permission) {
      if (CI::$APP->router->fetch_method() == 'api') {
        echo json_encode(array('status' => FALSE, 'message' => $this->lang->line('admin.access.denied', $this->uri->uri_string())));
        exit;
      } else {
        set_flash_error($this->lang->line('admin.access.denied', $this->uri->uri_string()));
        if (!userdata('admin_id') || !userdata('admin_username'))
          redirect('admin/login');
        else
          redirect('admin');
      }
    } else {
      $this->module = CI::$APP->router->fetch_module();
      $this->module_path = $this->module . '/';
      $this->module_lang = $this->module . '.';
      $this->class = get_class($this);
      $this->load->config('config', FALSE, FALSE, $this->module);
      $cache_time = $this->config->item('cache_full_page_time');
      if (!empty($cache_time)) {
        $this->output->cache($cache_time);
      } else {
        $cache_all_time = $this->config->item('cache_all_full_page_time');
        if (!empty($cache_all_time))
          $this->output->cache($cache_all_time);
      }
      if (file_exists(MODULES_PATH . $this->module . '/libraries/install' . EXT)) {
        $this->load->library('install');
        if (class_exists('install'))
          $this->install->run();
      }
      if ($this->class != 'logout') {
        if (!userdata('current_language_name')) {
          $language = $this->language_model->get_once(array('is_default' => TRUE));
          if (!empty($language)) {
            set_userdata('current_language_name', $language['slug']);
            set_userdata('current_language_id', $language['id']);
          } else {
            set_userdata('current_language_name', $this->config->item('language'));
            set_userdata('current_language_id', 0);
          }
        }
        $this->lang->is_loaded = array();
        $this->lang->language = array();
        $this->lang->load(userdata('current_language_name'), userdata('current_language_name'));
      }
    }
  }

  public function api($type = '', $method = 'list') {
    if (empty($type)) {
      echo '';
      return;
    }
    if (empty($method)) {
      echo $this->_api_render('json', array('status' => FALSE, 'message' => $this->lang->line('api.function.no.support', array($method, $this->class))));
      return;
    }
    $path = $this->module_path . $this->class . '/api/' . $type;
    $params = substr($_SERVER['REQUEST_URI'], strpos($_SERVER['REQUEST_URI'], $path) + strlen($path));
    if (str_endsWith($params, '/')) {
      $params = substr($params, 0, strlen($params) - 1);
    }
    $params = explode('/', $params);
    while (!empty($params) && empty($params[0]))
      array_shift($params);
    if (!empty($params)) {
      $method = $params[0];
      unset($params[0]);
    } else
      $method = 'list';
    if (method_exists($this, '_api_' . $method))
      echo $this->_api_render($type, call_user_func_array(array($this, '_api_' . $method), $params));
    else
      echo $this->_api_render($type, array('status' => FALSE, 'message' => $this->lang->line('api.function.no.support', array($method, $this->class))));
  }

  protected function _array_to_xml(array $arr, SimpleXMLElement $xml) {
    foreach ($arr as $k => $v)
      is_array($v) ? $this->_array_to_xml($v, $xml->addChild($k)) : $xml->addChild($k, $v);
    return $xml;
  }

  protected function _api_render($type, $params) {
    switch ($type) {
      case 'json':
        return json_encode($params);
        break;
      case 'xml':
        return $this->_array_to_xml($params, new SimpleXMLElement('<root/>'))->asXML();
        break;
      default :
        return json_encode(array('status' => FALSE, 'message' => $this->lang->line('api.no.support', $type)));
        break;
    }
  }

}

class NTB_Admin_Controller extends NTB_Core_Controller {

  public function __construct() {
    parent::__construct();
    if (!userdata('admin_id') || !userdata('admin_username')) {
      redirect('admin/login');
      return;
    }
  }

}

class NTB_Controller extends NTB_Admin_Controller {

  protected $model;
  protected $record_per_page = 10;

  public function __construct() {
    parent::__construct();
    $this->model = $this->router->fetch_class() . '_model';
    if (!isset($this->{$this->model}))
      $this->load->model($this->model);
    $this->model = $this->{$this->model};
  }

  protected function _pre_list() {
    return array();
  }

  public function index($max = '', $offset = '') {
    $max = empty($max) ? $max = $this->record_per_page : (int) $max;
    $offset = empty($offset) ? 0 : (int) $offset;
    $objs = $this->model->get_list(null, $max, $offset);
    $total = $this->model->total();
    if (!function_exists('paging'))
      $this->load->helper('paging');
    $paging = paging($this->module_path . $this->router->fetch_class() . '/index', $total, $max, $offset);
    $this->load->view($this->module_path . $this->router->fetch_class() . '/index', array_merge($this->_pre_list(), array('objs' => $objs, 'paging' => $paging, 'max' => $max, 'offset' => $offset)));
  }

  protected function _pre_form($id = '') {
    return array();
  }
  protected function _pre_save() {
    return true;
  }
  protected function _after_save($id) {
    return true;
  }
  protected function _pre_update() {
    return true;
  }
  protected function _after_update() {
    return true;
  }
  protected function _pre_delete($id = '') {
    return true;
  }
  protected function _after_delete($id = '', $obj = null) {
    return false;
  }
  public function create() {
    $this->load->view($this->module_path . $this->router->fetch_class() . '/create', $this->_pre_form());
  }
  public function save() {
    $this->_pre_save();
    $obj = $this->model->save($_POST);
    if (!empty($obj['validate_errors'])) {
      set_flash_error(lang($this->module_lang . $this->router->fetch_class() . '.save.error'));
      $this->load->view($this->module_path . $this->router->fetch_class() . '/create', array_merge($this->_pre_form(), array('obj' => $obj,
                  'errors' => $obj['validate_errors'])));
    } else {
      if (is_integer($obj)) {
        $this->_after_save($obj);
        set_flash_message(lang($this->module_lang . $this->router->fetch_class() . '.save.success'));
        redirect($this->module_path . $this->router->fetch_class() . '/edit/' . $obj);
      } else {
        set_flash_error(lang($this->module_lang . $this->router->fetch_class() . '.system.error'));
        $this->load->view($this->module_path . $this->router->fetch_class() . '/create', array_merge($this->_pre_form(), array('obj' => $obj, 'errors' => $obj['validate_errors'])));
      }
    }
  }

  public function edit($id = '') {
    $obj = $this->model->get_once($id);
    if (empty($obj)) {
      set_flash_error(lang($this->module_lang . $this->router->fetch_class() . '.not.found'));
      redirect($this->module_path . $this->router->fetch_class());
    } else {
      $this->load->view($this->module_path . $this->router->fetch_class() . '/edit', array_merge($this->_pre_form($id), array('obj' => $obj)));
    }
  }

  public function update() {
    $this->_pre_update();
    $obj = $this->model->save($_POST);
    if (!empty($obj['validate_errors'])) {
      set_flash_error(lang($this->module_lang . $this->router->fetch_class() . '.update.error'));
      $this->load->view($this->module_path . $this->router->fetch_class() . '/edit', array_merge($this->_pre_form(), array('obj' => $obj, 'errors' => $obj['validate_errors'])));
    } else {
      $this->_after_update($_POST['id']);
      set_flash_message(lang($this->module_lang . $this->router->fetch_class() . '.update.success'));
      redirect($this->module_path . $this->router->fetch_class() . '/edit/' . $_POST['id']);
    }
  }

  public function delete($id = '', $condition = array()) {
    $this->_pre_delete();
    if (!empty($condition)) {
      $condition['id'] = $id;
      $obj = $this->model->get_once($condition);
    } else
      $obj = $this->model->get_once($id);

    if (empty($obj)) {
      if (!empty($condition))
        set_flash_error(lang($this->module_lang . $this->router->fetch_class() . '.cannot.delete'));
      else
        set_flash_error(lang($this->module_lang . $this->router->fetch_class() . '.not.found'));
      redirect($this->module_path . $this->router->fetch_class());
    } else {
      $this->model->delete($id);
      $this->_after_delete($id, $obj);
      set_flash_message(lang($this->module_lang . $this->router->fetch_class() . '.delete.success'));
      redirect($this->module_path . $this->router->fetch_class());
    }
  }

  public function action() {
    if (empty($_POST['action'])) {
      set_flash_attention(lang($this->module_lang . $this->router->fetch_class() . '.no.action.selected'));
    } elseif (empty($_POST['ids'])) {
      set_flash_attention(lang($this->module_lang . $this->router->fetch_class() . '.no.record.selected'));
    } else {
      switch ($_POST['action']) {
        case 'delete':
          $this->model->delete(array('in' => array('id' => $_POST['ids'])));
          set_flash_message(lang($this->module_lang . $this->router->fetch_class() . '.selected.deleted'));
          break;
        default :
          set_flash_attention(lang($this->module_lang . $this->router->fetch_class() . '.action.no.support'));
          break;
      }
    }
    redirect($this->module_path . $this->router->fetch_class());
  }

  public function search($max = '', $offset = '', $conditions = '') {
    $max = empty($max) ? $max = $this->record_per_page : $max;
    $conditions = empty($conditions) ? null : $conditions;
    $objs = $this->model->get_list($conditions, $max, $offset);
    $total = $this->model->total($conditions);
    if (!function_exists('paging'))
      $this->load->helper('paging');
    $params = '?';
    foreach ($_GET as $key => $value)
      $params .= $key . '=' . $value . '&';
    if ($total > 0) {
      set_flash_message($this->lang->line($this->module_lang . $this->router->fetch_class() . '.search.result', $total));
    } else {
      set_flash_attention(lang($this->module_lang . $this->router->fetch_class() . '.search.result.empty'));
    }
    $paging = paging($this->module_path . $this->router->fetch_class() . '/search', $total, $max, $offset, null, $params);
    $this->load->view($this->module_path . $this->router->fetch_class() . '/index', array_merge($this->_pre_list(), array('objs' => $objs, 'paging' => $paging, 'params' => $_GET, 'max' => $max, 'offset' => $offset)));
  }

  protected function _api_list($max = '', $offset = '') {
    $max = empty($max) ? $max = $this->record_per_page : (int) $max;
    $offset = empty($offset) ? 0 : (int) $offset;
    $objs = $this->model->get_list(null, $max, $offset);
    $total = $this->model->total();
    return array('status' => TRUE, 'list_' . $this->class => $objs, 'total' => $total);
  }

  protected function _api_get($id = '') {
    $obj = $this->model->get_once($id);
    return array('status' => TRUE, $this->class => $obj);
  }

  protected function _api_delete($id = '') {
    $this->_pre_delete($id);
    $obj = $this->model->get_once($id);
    if (empty($obj)) {
      return array('stauts' => FALSE, 'message' => lang($this->module . '.' . $this->class . '.not.found'));
    } else {
      $this->model->delete($id);
      $this->_after_delete($id, $obj);
      return array('stauts' => TRUE, 'message' => lang($this->module . '.' . $this->class . '.delete.success'));
    }
  }

  protected function _api_save() {
    $this->_pre_save();
    $obj = $this->model->save($_POST);
    if (!empty($obj['validate_errors'])) {
      return array('status' => FALSE, 'message' => lang($this->module . '.' . $this->class . '.save.error'),
          'reasons' => $obj['validate_errors']);
    } else {
      if (is_integer($obj)) {
        $this->_after_save($obj);
        return array('status' => TRUE, 'message' => lang($this->module . '.' . $this->class . '.save.success'), 'id' => $obj);
      } else {
        return array('status' => FALSE, 'message' => lang($this->module . '.' . $this->class . '.save.error'),
            'reasons' => lang($this->module . '.' . $this->class . '.system.error'));
      }
    }
  }

  protected function _api_update() {
    $this->_pre_update();
    $obj = $this->model->save($_POST);
    if (!empty($obj['validate_errors'])) {
      return array('status' => FALSE, 'message' => lang($this->module . '.' . $this->class . '.update.error'),
          'reasons' => $obj['validate_errors']);
    } else {
      $this->_after_update();
      return array('status' => TRUE, 'message' => lang($this->module . '.' . $this->class . '.update.success'));
    }
  }

}
